package com.zyht.website.shiro;

import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import com.wx.entity.SysMenu;
import com.wx.entity.SysRole;
import com.wx.service.AuthorizationService;
import com.wx.service.impl.SpringContextHolder;
import com.zyht.bank.RoleEnum;
import com.zyht.website.entity.SysUser;
import com.zyht.website.service.SysUserService;
import com.zyht.website.shiro.AccountAuthorizationRealm.Principal;

/**
 * 
 * @author dingyaming
 *
 */
public class PermissionUtils {

	private static SysUserService userService = SpringContextHolder.getBean(SysUserService.class);

	private static AuthorizationService authorizationService = SpringContextHolder.getBean(AuthorizationService.class);

	public static final String USER_CACHE = "USER_CACHE:";
	public static final String USER_CACHE_ID = "USER_CACHE_ID:";
	public static final String USER_CACHE_LOGIN_NAME = "USER_CACHE_LOGIN_NAME:";

	public static final String CACHE_ROLE_LIST = "CACHE_ROLE_LIST";

	/**
	 * 当前用户的菜单缓存
	 */
	private static final String CACHE_USER_MENU_LIST = "CACHE_USER_MENU_LIST";

	/**
	 * 根据ID获取用户
	 * 
	 * @param id
	 * @return 取不到返回null
	 */
	public static SysUser get(Integer id){

		SysUser user = (SysUser) getCache(USER_CACHE + USER_CACHE_ID + id);
		if(user == null){
			user = userService.selectByPrimaryKey(id);
			if(user == null){
				return null;
			}
			putCache(USER_CACHE + USER_CACHE_ID + user.getId(),user);
			putCache(USER_CACHE + USER_CACHE_LOGIN_NAME + user.getUsername(),user);
		}
		return user;
	}

	/**
	 * 根据登录名获取用户
	 * 
	 * @param loginName
	 * @return 取不到返回null
	 */
	public static SysUser getByLoginName(String loginName){

		SysUser user = (SysUser) getCache(USER_CACHE + USER_CACHE_LOGIN_NAME + loginName);
		if(user == null){
			user = userService.selectBySysUserName(loginName);
			if(user == null){
				return null;
			}
			putCache(USER_CACHE + USER_CACHE_ID + user.getId(),user);
			putCache(USER_CACHE + USER_CACHE_LOGIN_NAME + user.getUsername(),user);
		}
		return user;
	}

	/**
	 * 清除当前用户缓存
	 */
	public static void clearCache(){

		removeCache(CACHE_ROLE_LIST);
		removeCache(CACHE_USER_MENU_LIST);
		PermissionUtils.clearCache(getUser());
	}

	/**
	 * 清除指定用户缓存
	 * 
	 * @param user
	 */
	public static void clearCache(SysUser user){

		removeCache(USER_CACHE + USER_CACHE_ID + user.getId());
		removeCache(USER_CACHE + USER_CACHE_LOGIN_NAME + user.getUsername());
	}

	/**
	 * 获取当前用户
	 * 
	 * @return 取不到 throw new UnauthenticatedException();
	 * @throws UnauthenticatedException
	 */
	public static SysUser getUser(){

		Principal principal = getPrincipal();
		if(principal != null){
			SysUser user = get(Integer.valueOf(principal.getId()));
			if(user != null && user.getId() != null){
				return user;
			}
			throw new UnauthenticatedException();
		}
		// 如果没有登录，则返回实例化空的User对象。
		throw new UnauthenticatedException();
	}

	/**
	 * 获取当前用户角色列表
	 */
	public static List<SysRole> getRoleList(){
		List<SysRole> roleList = (List<SysRole>) getCache(CACHE_ROLE_LIST);
		if(roleList == null){
			SysUser user = getUser();
			roleList = authorizationService.findRolesByUserId(user.getId());
			if(roleList == null || roleList.isEmpty()){
				roleList = new ArrayList<SysRole>();
			}

			putCache(CACHE_ROLE_LIST,roleList);
		}
		return roleList;
	}

	public static List<Integer> getRoleIdList(){

		List<SysRole> roleList = getRoleList();
		List<Integer> roleidList = new ArrayList<Integer>();
		for(SysRole sysRole:roleList){
			roleidList.add(sysRole.getId());
		}
		return roleidList;
	}

	/**
	 * <b>作者:</b> Bob<br/>
	 * <b>修改时间：</b>2017年6月28日 - 下午5:28:57<br/>
	 * <b>功能说明：获取当前用户授权菜单</b>	<br/>
	 * @return
	 */
	public static List<SysMenu> getMenuList(){
		List<SysMenu> menuList = (List<SysMenu>) getCache(CACHE_USER_MENU_LIST);
		if(menuList == null){
			menuList = new ArrayList<SysMenu>();
			SysUser user = getUser();
			List<SysRole> roles = getRoleList();
			boolean isSystemAdmin = false;
			for (SysRole sysRole : roles) {
				if(RoleEnum.SYSTEM.getCode().equals(sysRole.getRoleCode())){
					isSystemAdmin = true;
					break;
				}
			}
			List<SysMenu> menuList1 = null;
			if(isSystemAdmin){
				menuList1 = getAllMenus();
			}else{
				menuList1 = authorizationService.findAllMenusByUserId(user.getId());
			}
			if(menuList1 != null && !menuList1.isEmpty()){
				menuList.addAll(menuList1);
			}
			putCache(CACHE_USER_MENU_LIST,menuList);
		}
		return menuList;
	}

	/**
	 * <b>作者:</b> Bob<br/>
	 * <b>修改时间：</b>2017年6月28日 - 下午5:26:33<br/>
	 * <b>功能说明：获取所有的菜单和权限</b>	<br/>
	 * @return
	 */
	public static List<SysMenu> getAllMenus(){

		List<SysMenu> menuList = (List<SysMenu>) getCache(CACHE_USER_MENU_LIST);
		if(null == menuList){
			menuList = authorizationService.findAllMenus();
			putCache(CACHE_USER_MENU_LIST,menuList);
		}
		return menuList;
	}

	/**
	 * 获取授权主要对象
	 */
	public static Subject getSubject(){

		return SecurityUtils.getSubject();
	}

	/**
	 * 获取当前登录者对象
	 */
	public static Principal getPrincipal(){

		try{
			Subject subject = SecurityUtils.getSubject();
			Principal principal = (Principal) subject.getPrincipal();
			if(principal != null){
				return principal;
			}
		} catch (UnavailableSecurityManagerException e){

		} catch (InvalidSessionException e){

		}
		return null;
	}

	public static Session getSession(){

		try{
			Subject subject = SecurityUtils.getSubject();
			Session session = subject.getSession(false);
			if(session == null){
				session = subject.getSession();
			}
			if(session != null){
				return session;
			}
			// subject.logout();
		} catch (InvalidSessionException e){

		}
		return null;
	}

	// ============== User Cache ==============

	public static Object getCache(String key){

		return getCache(key,null);
	}

	public static Object getCache(String key,Object defaultValue){

		Object obj = getSession().getAttribute(key);
		return obj == null ? defaultValue : obj;
	}

	public static void putCache(String key,Object value){

		getSession().setAttribute(key,value);
	}

	public static void removeCache(String key){

		getSession().removeAttribute(key);
	}

	/**
	 * 验证权限
	 * 
	 * @author:InkYi
	 * @time:2016年8月27日 - 下午6:34:53
	 * @description:
	 * @param roleid
	 * @return 有-true 无-false
	 */
	public static boolean validateRole(Integer roleid){

		List<Integer> roleIdList = getRoleIdList();
		if(roleIdList.contains(roleid)){
			return true;
		}
		return false;
	}

}
